package darksideoftheloom;
/**
 * WeavingDraft.java
 *
 * @Author Joshua Warner
 * @Version 1.0
 * @Date Feruary 16, 2013
 * Purpose: to hold and be able to modify a 
 *          weaving draft using standard
 *          parts and usage of weaving drafts.
 *
 * Standard weaving Treminology and patterns will be used for this class
 * as such the Threading if the upper left of a draft, the 
 * tie up is the upper right, the Treadling is the lower right, 
 * and the body or lower left is the Drawdown.
 *
 *             Threading            Tie Up
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * _______________________________||_______
 * _______________________________||_______
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 * -------------------------------||-------
 *           Drawdown              Treadling
 */
public class WeavingDraft{

    /*
     * Attributes
     */

    /**
     * treadling
     *
     * for simplicity even though a Treadling 
     * chart starts with the first row of the
     * weave to be at the lower left, the 
     * treadling chart will be saved in the 
     * following way for ease of programming
     * and/or programming consistancy.
     *
     *       normal Treadling
     *      [ ][ ][ ][X] (row 10)
     *      [ ][ ][X][ ] (row 9)
     *      [ ][ ][ ][x] (row 8)
     *      [ ][ ][X][ ] (row 7)
     *      [ ][ ][X][ ] (row 6)
     *      [ ][ ][X][ ] (row 5)
     *      [X][ ][ ][ ] (row 4)
     *      [ ][ ][X][ ] (row 3)
     *      [ ][X][ ][ ] (row 2)
     *      [ ][ ][X][ ] (row 1)
     *
     *    same Treadling in boolean array
     *    {{0,0,0,1},  (row 10 -> pedalChart[0])
     *     {0,0,1,0},  (row 9 -> pedalChart[1])
     *     {0,0,0,1},  (row 8 -> pedalChart[2])
     *     {0,0,1,0},  (row 7 -> pedalChart[3])
     *     {0,0,1,0},  (row 6 -> pedalChart[4])
     *     {0,0,1,0},  (row 5 -> pedalChart[5])
     *     {1,0,0,0},  (row 4 -> pedalChart[6])
     *     {0,0,1,0},  (row 3 -> pedalChart[7])
     *     {0,1,0,0},  (row 2 -> pedalChart[8])
     *     {0,0,1,0}}  (row 1 -> pedalChart[9])
     *
     */
    private final boolean[][] my_treadling;

    /**
     *threading
     *
     *the following is how to read/write the threading
     *so that this class will read it correctly.
     *
     *       normal threading
     *    [X][ ][ ][ ][X][ ][ ][ ][ ][ ][X][ ][ ][ ][X]
     *    [ ][X][ ][ ][ ][X][ ][ ][ ][X][ ][ ][ ][X][ ]
     *    [ ][ ][X][ ][ ][ ][X][ ][X][ ][ ][ ][X][ ][ ]
     *    [ ][ ][ ][X][ ][ ][ ][x][ ][ ][ ][X][ ][ ][ ]
     *
     *
     *      same threading in boolean array
     *   {{1,0,0,0,1,0,0,0,0,0,1,0,0,0,1},
     *    {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0},
     *    {0,0,1,0,0,0,1,0,1,0,0,0,1,0,0},
     *    {0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}}
     */
    private final boolean[][] my_threading;

    /**
     *Tie up
     *
     *The following is how to read/write the tie up 
     *so that this class will read it correctly.
     *
     *    normal Tie Up
     *    [ ][ ][X][X]
     *    [X][X][ ][X]
     *    [ ][X][ ][X]
     *    [X][ ][X][ ]
     *
     *
     * Same Tie Up in Boolean array
     *   {{0,0,1,1},
     *    {1,1,0,1},
     *    {0,1,0,1},
     *    {1,0,1,0},
     */
    private final boolean[][] my_tie_up;

    /**
     * Drawdown
     *
     * the following is how to read/write the drawdown
     *so that this class will read it correctly.
     *
     *       normal Drawdown
     *    [X][ ][ ][ ][X][ ][ ][ ][ ][ ][X][ ][ ][ ][X]
     *    [ ][X][ ][ ][ ][X][ ][ ][ ][X][ ][ ][ ][X][ ]
     *    [ ][ ][X][ ][ ][ ][X][ ][X][ ][ ][ ][X][ ][ ]
     *    [ ][ ][ ][X][ ][ ][ ][x][ ][ ][ ][X][ ][ ][ ]
     *    [X][ ][ ][ ][X][ ][ ][ ][ ][ ][X][ ][ ][ ][X]
     *    [X][ ][ ][ ][X][ ][ ][ ][ ][ ][X][ ][ ][ ][X]
     *    [ ][ ][ ][X][ ][ ][ ][x][ ][ ][ ][X][ ][ ][ ]
     *    [ ][ ][X][ ][ ][ ][X][ ][X][ ][ ][ ][X][ ][ ]
     *    [ ][X][ ][ ][ ][X][ ][ ][ ][X][ ][ ][ ][X][ ]
     *    [X][ ][ ][ ][X][ ][ ][ ][ ][ ][X][ ][ ][ ][X]
     *
     *
     *      Same Drawdown in boolean array
     *   {{1,0,0,0,1,0,0,0,0,0,1,0,0,0,1},
     *    {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0},
     *    {0,0,1,0,0,0,1,0,1,0,0,0,1,0,0},
     *    {0,0,0,1,0,0,0,1,0,0,0,1,0,0,0},
     *    {1,0,0,0,1,0,0,0,0,0,1,0,0,0,1},
     *    {1,0,0,0,1,0,0,0,0,0,1,0,0,0,1},
     *    {0,0,0,1,0,0,0,1,0,0,0,1,0,0,0},
     *    {0,0,1,0,0,0,1,0,1,0,0,0,1,0,0},
     *    {0,1,0,0,0,1,0,0,0,1,0,0,0,1,0},
     *    {1,0,0,0,1,0,0,0,0,0,1,0,0,0,1}}
     */
    private final boolean[][] my_drawdown;


    /*
     * Methods
     */

    /**
     * Constructor
     *
     *creates a new blank draft with the given
     *threading dimentions and treadling dimensions.
     *@Param threading_height the height of the threading and tie up
     *@Param threading_width the width of the threading and final weave
     *@Param treadling_height the height of the treadling and final weave
     *@Param treadling_width the width of the treadling and tie up
     */
    public WeavingDraft(int threading_height, int threading_width,
                        int treadling_height, int treadling_width){
        
        //create correct heights for the four parts
        my_threading = new boolean[threading_height][];
        my_tie_up = new boolean[threading_height][];
        my_treadling = new boolean[treadling_height][];
        my_drawdown = new boolean[treadling_height][];
        
        //create correct widths for the four parts
        for(int i = 0; i < threading_height; i++){
            my_threading[i] = new boolean[threading_width];
            my_tie_up[i] = new boolean[treadling_width];
        }
        for(int i = 0; i < treadling_height; i++){
            my_treadling[i] = new boolean[treadling_width];
            my_drawdown[i] = new boolean[threading_width];
        }
    }

    /**
     *changeThreading
     *
     *modify the given threading point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeThreading(int row, int column, boolean new_value){
        my_threading[row][column] = new_value;

        for(int i = 0; i < my_drawdown.length; i++){
            updateDrawdown(i, column);            
        }
    }
    
    /**
     *changeThreading
     *
     *modify the given threading point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeThreading(int row, int column){
        my_threading[row][column] = !(my_threading[row][column]);
    	
        for(int i = 0; i < my_drawdown.length; i++){
            updateDrawdown(i, column);
        }
        
    }


    /**
     *changeTreadling
     *
     *modify the given treadling point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeTreadling(int row, int column, boolean new_value){
        my_treadling[row][column] = new_value;

        for(int i = 0; i < my_drawdown[row].length; i++){
            updateDrawdown(row, i);
        }
    }
    
    /**
     *changeTreadling
     *
     *modify the given treadling point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeTreadling(int row, int column){
        my_treadling[row][column] = !(my_treadling[row][column]);

        for(int i = 0; i < my_drawdown[row].length; i++){
            updateDrawdown(row, i);
        }
    }


    /**
     *changeTieUP
     *
     *modify the given tie up point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeTieUp(int row, int column, boolean new_value){
        my_tie_up[row][column] = new_value;

        for(int i = 0; i < my_drawdown.length; i++){
            for(int j = 0; j < my_drawdown[i].length; j++){
                updateDrawdown(i, j);
            }
        }
    }
    
    /**
     *changeTieUP
     *
     *modify the given tie up point and update the drawdown
     *@Param row the row of the point to change
     *@Param column the column of the point to change
     *@Param new_value the value to change the point to
     */
    public void changeTieUp(int row, int column){
        my_tie_up[row][column] = !(my_tie_up[row][column]);

        for(int i = 0; i < my_drawdown.length; i++){
            for(int j = 0; j < my_drawdown[i].length; j++){
                updateDrawdown(i, j);
            }
        }
    }

    /**
     *updateDrawdown
     *
     *Updates the given point in the drawdown.
     *@Param row the row of the point that needs to be updated.
     *@Param column the column of the point that needs to be updated.
     */
    private void updateDrawdown(int row, int column){

        boolean location_marked = false;

        for(int tread = 0; tread < my_treadling[row].length; tread++){
            for(int tie = 0; tie < my_tie_up.length; tie++){
                if(my_treadling[row][tread] && 
                   my_tie_up[tie][tread] &&
                   my_threading[tie][column]){
                    location_marked = true;
                    break;
                }
            }
        }

        my_drawdown[row][column] = location_marked;
    }

    /*
     * Getters
     */
    public boolean[][] getThreading(){
        return my_threading;
    }

    public boolean[][] getTreadling(){
        return my_treadling;
    }

    public boolean[][] getTieUp(){
        return my_tie_up;
    }

    public boolean[][] getDrawdown(){
        return my_drawdown;
    }
}